package com.beardedhen.harmonybootstrap;

import com.beardedhen.harmonybootstrap.utils.UiUtil;

import ohos.agp.components.Attr;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.app.Context;

import java.util.Optional;

public class BootstrapProgressBarGroup extends BootstrapGroup{

    private int cumulativeProgress;
    private int maxProgress;

    private final BootstrapProgressBar emptyProgressBar = new BootstrapProgressBar(getContext(), new AttrSet() {
        @Override
        public Optional<String> getStyle() {
            return Optional.empty();
        }

        @Override
        public int getLength() {
            return 0;
        }

        @Override
        public Optional<Attr> getAttr(int i) {
            return Optional.empty();
        }

        @Override
        public Optional<Attr> getAttr(String s) {
            return Optional.empty();
        }
    });
    private int sizeOrdinal;
    private boolean isEmptyBeingAdded = false;
    private boolean rounded;
    private static final String BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_MAX_PROGRESS = "bootstrapMlaxProgress";
    private static final String BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_SIZE = "bootstrapSize";
    private static final String BOOTSTRAP_PROGRESS_BAR_GROUP_ROUNDED_CORNERS = "roundedCorners";

    public BootstrapProgressBarGroup(Context context) {
        super(context);
    }

    public BootstrapProgressBarGroup(Context context, AttrSet attrs) {
        super(context, attrs);
    }

    public BootstrapProgressBarGroup(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void initialise(AttrSet attrs) {
        try {
            this.maxProgress = attrs.getAttr(BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_MAX_PROGRESS).isPresent()?attrs.getAttr(
                BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_MAX_PROGRESS).get().getIntegerValue(): 100;
            this.sizeOrdinal = 2;
            if (attrs.getAttr(BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_SIZE).isPresent()) {
                String sizeOrdinalStr = attrs.getAttr(BOOTSTRAP_PROGRESS_BAR_GROUP_BOOTSTRAP_SIZE).get().getStringValue().trim();
                this.sizeOrdinal = UiUtil.getBootstrapSizeInt(sizeOrdinalStr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        setOrientation(HORIZONTAL);
        updateBootstrapGroup();
    }

    @Override
    protected void updateBootstrapGroup() {
        if (getChildCount() == 0) {
            return;
        }

        cumulativeProgress = getCumulativeProgress();

        int numChildren = getChildCount();
        for (int i = 0; i < numChildren; i++) {
            LayoutConfig layoutParams = (LayoutConfig) getLayoutConfig();
            layoutParams.weight = retrieveChild(i).getProgress();
            retrieveChild(i).setLayoutConfig(layoutParams);

            retrieveChild(i).setMaxProgress(retrieveChild(i).getProgress());
            retrieveChild(i).setBootstrapSize(sizeOrdinal);

            retrieveChild(i).setRounded(rounded);
        }

        //update empty progressbar attributes
        LayoutConfig layoutParams = (LayoutConfig) getLayoutConfig();
        layoutParams.weight = (float) maxProgress - cumulativeProgress;
        emptyProgressBar.setLayoutConfig(layoutParams);
        emptyProgressBar.setMaxProgress(maxProgress - cumulativeProgress);
        emptyProgressBar.setBootstrapSize(sizeOrdinal);

        setTotalWeight((float)maxProgress);
    }

    @Override
    protected void onBootstrapViewRemoved() {
        addEmptyProgressBar();

        updateBootstrapGroup();
    }

    @Override
    protected void onBootstrapViewAdded() {
        addEmptyProgressBar();

        updateBootstrapGroup();
    }

    /**
     * This looks for instances of emptyProgressBar and removes them if they are not at the end and then adds one at the end if its needed.
     */
    private void addEmptyProgressBar(){
        int whereIsEmpty = -1;
        for (int i = 0; i < getChildCount(); i++) {
            if (retrieveChild(i) != null && retrieveChild(i).equals(emptyProgressBar)) {
                whereIsEmpty = i;
            }
        }

        if (whereIsEmpty != getChildCount() - 1) {
            if (whereIsEmpty != -1) {
                //the flowing true/false is to stop empty progressbar being added more than once as removeView and addView indirectly call this method
                isEmptyBeingAdded = true;
                removeComponent(emptyProgressBar);
                isEmptyBeingAdded = false;
            }
            if (!isEmptyBeingAdded) {
                addComponent(emptyProgressBar);
            }
        }
    }

    /**
     * This get the total progress of all the children
     * @return the CumulativeProgress i.e. the total progress of all children
     */
    public int getCumulativeProgress(){
        int numChildren = getChildCount();
        int total = 0;
        for (int i = 0; i < numChildren; i++) {
            total += getChildProgress(i);
        }
        checkCumulativeSmallerThanMax(maxProgress, total);
        return total;
    }

    private int getChildProgress(int i){
        return retrieveChild(i).getProgress();
    }

    private BootstrapProgressBar retrieveChild(int i) {
        Component view = getComponentAt(i);

        if ((view instanceof BootstrapProgressBar)) {
            return (BootstrapProgressBar) view;
        }
        else {
            throw new IllegalStateException("All child view of BootstrapProgressBarGroup must be BootstrapProgressBar");
        }
    }

    private void checkCumulativeSmallerThanMax(int max, int cumulative){
        StringBuilder builder = new StringBuilder();
        builder.append("Max Progress Cant be smaller than cumulative progress. Max = ");
        builder.append(max);
        builder.append(", cumlative = ");
        builder.append(cumulative);
        builder.append(". \n");
        for (int i = 0; i < getChildCount(); i++) {
            builder.append("Child ").append(i).append(" has progress ").append(getChildProgress(i));
        }
        if (max < cumulative){
            throw new IllegalStateException(builder.toString());
        }

    }

    public void onProgressChanged(BootstrapProgressBar bootstrapProgressBar){
        updateBootstrapGroup();
    }

}
